/*
 * Copyright (C), 2002-2016, 苏宁易购电子商务有限公司
 * FileName: TmBatchUpdateAction.java
 * Author:   15050536
 * Date:     2016年12月14日 下午4:15:46
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.suning.sawp.service.impl.tm;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.beanutils.BeanMap;
import org.apache.commons.lang3.StringUtils;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.suning.istore.lang.BufferedAction.Action;
import com.suning.sawp.constants.TMCategoryEnum;
import com.suning.sawp.constants.TMConstants;
import com.suning.sawp.intf.dao.tm.TimeMachineDao;
import com.suning.sawp.intf.tm.vo.AllSaleInfoVo;
import com.suning.sawp.intf.tm.vo.CategoryInfoVo;
import com.suning.sawp.intf.tm.vo.EmployeeHireInfoVo;
import com.suning.sawp.intf.tm.vo.ExpensiveSaleVo;
import com.suning.sawp.intf.tm.vo.FirstSaleInfoVo;
import com.suning.sawp.intf.tm.vo.MemberInfoVo;
import com.suning.sawp.intf.tm.vo.ThisYearSaleInfoVo;
import com.suning.sawp.intf.tm.vo.TimeMachineVo;
import com.suning.sawp.intf.tm.vo.TotalSaleInfoVo;
import com.suning.sawp.intf.tm.vo.TypePercentVo;
import com.suning.sawp.po.tm.EmployeeExpensiveSaleInfo;
import com.suning.sawp.po.tm.EmployeeFirstSaleInfo;
import com.suning.sawp.service.impl.bi.BatchUpdateService;
import com.suning.sawp.service.util.NumberUtils;
import com.suning.sawp.service.util.RedisCacheUtils;

/**
 * 批处理ftp文件数据
 *
 * @author 15050536 石键平
 */
public class TmBatchUpdateAction<T> implements Action<T> {

	private Gson gson = new Gson();

	BatchUpdateService batchUpdateService;

	TimeMachineDao timeMachineDao;

	private RedisCacheUtils cacheUtils;

	private String sqlId;

	@SuppressWarnings("rawtypes")
	private Class clazz;
	
	private HandleFillVo handleFillVo = new HandleFillVo();
	
	@SuppressWarnings("rawtypes")
	public TmBatchUpdateAction(String sqlId, BatchUpdateService batchUpdateService, TimeMachineDao timeMachineDao, RedisCacheUtils cacheUtils, Class clazz) {
		this.sqlId = sqlId;
		this.batchUpdateService = batchUpdateService;
		this.timeMachineDao = timeMachineDao;
		this.clazz = clazz;
		this.cacheUtils = cacheUtils;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void action(T[] objs) {
		Map<String, Object>[] batchValues = Iterables.toArray(Iterables.transform(Lists.newArrayList(objs), new Function<T, Map<String, Object>>() {
			@Override
			public Map<String, Object> apply(T input) {
				return new BeanMap(input);
			}
		}), Map.class);

		//先入库
		batchUpdateService.batchUpdate(sqlId, batchValues);
		final Map<String,Object> tmpMap[] = batchValues;
		setDateInCache(tmpMap);
	}

	private void setDateInCache(Map<String, Object>[] batchValues) {
		if (batchValues == null || batchValues.length == 0) {
			return;
		}
		
		String className = clazz.getSimpleName();
		
		if ("BiEmployeeHireInfoEntity".equals(className)) {
			for (Map<String, Object> data : batchValues) {
				fillEmployeeHireInfo(data);
			}
		} else if ("BiEmployeeFirstSaleInfoEntity".equals(className)) {
			for (Map<String, Object> data : batchValues) {
				fillFirstSaleInfoVo(data);
			}
		} else if ("BiEmployeeTotalSaleInfoEntity".equals(className)) {
			for (Map<String, Object> data : batchValues) {
				fillTotalSaleInfoVo(data);
			}
		} else if ("BiEmployeeExpensiveSaleInfoEntity".equals(className)) {
			for (Map<String, Object> data : batchValues) {
				fillExpensiveSaleVo(data);
			}
		} else if ("BiEmployeeCategoryInfoEntity".equals(className)) {
			for (Map<String, Object> data : batchValues) {
				fillCategoryInfoVo(data);
			}
		} else if ("BiEmployeeMemberInfoEntity".equals(className)) {
			for (Map<String, Object> data : batchValues) {
				fillMemberInfoVo(data);
			}
		}

	}


	/**
	 * 读取员工数据，插入redis
	 *
	 * @param data
	 */
	private void fillEmployeeHireInfo(Map<String, Object> data) {
		
		String employeeId = (String) data.get("employeeId");
		String gender = (String) data.get("gender");
		String hireTime = (String) data.get("hireTime");
		Integer hireMonth = (Integer) data.get("hireMonth");

		int totalDay = (Integer) data.get("hireDay");
		int ranking = (Integer) data.get("ranking");
		int countAll = (Integer) data.get("countAll");
		String percent = NumberUtils.calculatePercent(countAll - ranking, countAll);

		String hasGotCoupon = TMConstants.UN_GOT_COUPON;
		
		//查询用户是否领取过优惠券
		Map<String, Object> map = timeMachineDao.findReceiveCouponByEmployeeId(employeeId);
		if (map != null && map.size() > 0) {
			hasGotCoupon = TMConstants.HAS_GOT_COUPON;
		}
		//ftp获取的性别是1，2;需要转换成 M,F
		String sex = TMConstants.FAMALE_NUM.equals(gender) ? TMConstants.FAMALE : TMConstants.MAN; 
		EmployeeHireInfoVo hireInfoVo = new EmployeeHireInfoVo(employeeId, sex, String.valueOf(totalDay), hireTime, percent, hasGotCoupon,String.valueOf(hireMonth));

		// 更新缓存中数据
		TimeMachineVo timeMachineVo = queryDataFromCache(employeeId);
		timeMachineVo.setUserInfo(hireInfoVo);
		saveDateInCache(employeeId, timeMachineVo);
	}

	/**
	 * 读取首单数据，插入redis
	 *
	 * @param data
	 */
	private void fillFirstSaleInfoVo(Map<String, Object> data) {
		//工号
		String employeeId = (String) data.get("employeeId");
		//销售日期
		String saleDate = (String) data.get("saleDate");
		//单价
		BigDecimal price = (BigDecimal) data.get("price");
		// 付款总金额
		BigDecimal amount = (BigDecimal) data.get("payAmnt");
		//类别
		String type = (String) data.get("cateCode");
		//商品名称
		String cmmdtyName = (String) data.get("cmmdtyName");
		// 商品数量
		Integer num = (Integer) data.get("num");
		
		//构建bean
		EmployeeFirstSaleInfo employeeFirstSaleInfo = new EmployeeFirstSaleInfo(employeeId,price,num,amount,cmmdtyName,saleDate,type);
		//构建vo
		FirstSaleInfoVo firstSaleInfoVo = handleFillVo.fillFirstSaleInfoVo(employeeFirstSaleInfo);

		// 更新缓存中数据
		TimeMachineVo timeMachineVo = queryDataFromCache(employeeId);
		AllSaleInfoVo allSaleInfoVo = timeMachineVo.getAllSaleInfo();
		if (allSaleInfoVo == null) {
			allSaleInfoVo = new AllSaleInfoVo();
		}
		allSaleInfoVo.setFirst(firstSaleInfoVo);
		timeMachineVo.setAllSaleInfo(allSaleInfoVo);
		saveDateInCache(employeeId, timeMachineVo);
	}

	/**
	 * 读取总销售记录信息，插入redis
	 */
	private void fillTotalSaleInfoVo(Map<String, Object> data) {
		TotalSaleInfoVo totalSaleInfoVo = new TotalSaleInfoVo();

		String employeeId = (String) data.get("employeeId");
		BigDecimal amount = (BigDecimal) data.get("amount");

		totalSaleInfoVo.setAmount(amount.toPlainString());
		// 总订单数
		int orderNum = (Integer) data.get("orderNum");
		totalSaleInfoVo.setOrderNum(String.valueOf(orderNum));

		// 更新缓存中数据
		TimeMachineVo timeMachineVo = queryDataFromCache(employeeId);
		//总销售信息
		AllSaleInfoVo allSaleInfoVo = timeMachineVo.getAllSaleInfo();
		if (allSaleInfoVo == null) {
			allSaleInfoVo = new AllSaleInfoVo();
		}
		allSaleInfoVo.setTotal(totalSaleInfoVo);
		timeMachineVo.setAllSaleInfo(allSaleInfoVo);
		saveDateInCache(employeeId, timeMachineVo);
	}

	/**
	 * 读取2016年最贵的销售记录信息，插入redis
	 *
	 * @return
	 */
	private void fillExpensiveSaleVo(Map<String, Object> data) {
		
		//工号
		String employeeId = (String) data.get("employeeId");
		//类目
		String type = (String) data.get("cateCode");
		//支付金额
		BigDecimal payAmnt = (BigDecimal) data.get("payAmnt");
		//销售日期
		String saleDate = (String) data.get("saleDate");
		//商品名称
		String cmmdtyName = (String) data.get("cmmdtyName");
		// 商品数量
		Integer num = (Integer) data.get("num");
		//顾客姓名
		String customName = (String) data.get("customName");
		//顾客性别
		String gender = (String) data.get("gender");
		//根据数据生成bean
		EmployeeExpensiveSaleInfo mostSaleInfo = new EmployeeExpensiveSaleInfo(employeeId,num,payAmnt,cmmdtyName,type,saleDate,customName,gender);
		//生成vo
		ExpensiveSaleVo expensiveSaleVo = handleFillVo.fillExpensiveSaleVo(mostSaleInfo);

		// 更新缓存中数据
		TimeMachineVo timeMachineVo = queryDataFromCache(employeeId);
		//当前年份信息
		ThisYearSaleInfoVo thisYearSaleInfo = timeMachineVo.getThisYearSaleInfo();
		if (thisYearSaleInfo == null) {
			thisYearSaleInfo = new ThisYearSaleInfoVo();
		}
		thisYearSaleInfo.setMostSale(expensiveSaleVo);
		timeMachineVo.setThisYearSaleInfo(thisYearSaleInfo);
		saveDateInCache(employeeId, timeMachineVo);

	}

	/**
	 * 读取2016年按品类分组 计算各品类占销售的百分比，插入redis
	 *
	 * @return
	 */
	private void fillCategoryInfoVo(Map<String, Object> data) {
		CategoryInfoVo categoryInfoVo = new CategoryInfoVo();
		
		//工号
		String employeeId = (String) data.get("employeeId");
		//总金额
		BigDecimal payAmntAll = (BigDecimal) data.get("payAmntAll");
		
		if (payAmntAll == null) {
			return;
		}
		
		List<TypePercentVo> typePercent = new ArrayList<TypePercentVo>();

		for (TMCategoryEnum te : TMCategoryEnum.values()) {
			String code = te.getCode();
			//00011，00019忽略
			if (TMCategoryEnum.CATE_00011.getCode().equals(code) || TMCategoryEnum.CATE_00019.getCode().equals(code) ){
				continue;
			}
			//other 改为Other	
			if(TMCategoryEnum.CATE_OTHER.getCode().equals(code)) {
				code = "Other";
			}
			String key = "payAmnt" + code;
			BigDecimal payAmnt = (BigDecimal) data.get(key);
			// 构造各个分类数据
			handleFillVo.setTypePercent(payAmnt, payAmntAll, te, typePercent);
		}
		//按销售百分比，排个序
		Collections.sort(typePercent);
		categoryInfoVo.setTypePercent(typePercent);

		// 更新缓存中数据
		TimeMachineVo timeMachineVo = queryDataFromCache(employeeId);
		ThisYearSaleInfoVo thisYearSaleInfo = timeMachineVo.getThisYearSaleInfo();
		if (thisYearSaleInfo == null) {
			thisYearSaleInfo = new ThisYearSaleInfoVo();
		}
		thisYearSaleInfo.setStatictisInfo(categoryInfoVo);
		timeMachineVo.setThisYearSaleInfo(thisYearSaleInfo);
		saveDateInCache(employeeId, timeMachineVo);
	}

	/**
	 * 设置会员信息 插入redis
	 *
	 * @param data
	 */
	private void fillMemberInfoVo(Map<String, Object> data) {
		String employeeId = (String) data.get("employeeId");

		MemberInfoVo memberInfoVo = new MemberInfoVo();
		String customName = handleFillVo.getCustomName((String) data.get("customName"), (String) data.get("gender"));
		memberInfoVo.setName(customName);
		memberInfoVo.setNum(String.valueOf(data.get("orderNum")));
		memberInfoVo.setOldMemberNum(String.valueOf(data.get("oldMemberNum")));
		memberInfoVo.setAllMemberNum(String.valueOf(data.get("memberNum")));

		// 塞到缓存中去
		saveMemberInfoInCache(employeeId, memberInfoVo);

	}


	/**
	 * 从缓存中获取数据
	 *
	 * @param employeeId
	 * @return
	 */
	private TimeMachineVo queryDataFromCache(String employeeId) {
		String data = cacheUtils.get(TMConstants.TIME_MACHINE_KEY + employeeId);
		if (StringUtils.isNotEmpty(data)) {
			return gson.fromJson(data, TimeMachineVo.class);
		}
		return new TimeMachineVo();
	}

	/**
	 * 把员工时光机数据塞入缓存
	 *
	 * @param employeeId
	 * @param data
	 */
	private void saveDateInCache(String employeeId, TimeMachineVo timeMachineVo) {
		if (timeMachineVo == null) {
			return;
		}
		String data = gson.toJson(timeMachineVo);
		cacheUtils.setex(TMConstants.TIME_MACHINE_KEY + employeeId,TMConstants.EXPIRE_TIME, data);
	}
	
	/**
	 * 把接待的老客户信息放入缓存,每次存数据前会删除缓存的老用户数据
	 *
	 * @param employeeId
	 * @param memberInfo
	 */
	private void saveMemberInfoInCache(String employeeId, MemberInfoVo memberInfo) {
		if (memberInfo == null) {
			return;
		}
		String key = TMConstants.TIME_MACHINE_MEMBER_KEY + employeeId;
		cacheUtils.lpush(key, gson.toJson(memberInfo));
	}

}
